﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Collections;


/*
namespace repliback4.Net.Requests.Serialization {

    public class TypeMapping {
        protected Dictionary<String, Type> list = new Dictionary<String, Type>( );

        public void AddType ( Type type ) {
            Attributes.Request[] rq = ( Attributes.Request[] ) type.GetCustomAttributes( typeof( Attributes.Request ), true );
            Attributes.RequestClass[] rqcl = ( Attributes.RequestClass[] ) type.GetCustomAttributes( typeof( Attributes.RequestClass ), true );
            String name = rq.Length > 0 ? rq[rq.Length - 1].Name : "request";
            String prefix = rqcl.Length > 0 ? rqcl[rqcl.Length - 1].Name : "request";

            this.list.Add( prefix + ":" + name, type );

            //this.list.Add( type );
            //type.GetCustomAttributes(
            //type.Attributes
        }


        public Type GetMappedType ( string name ) {
            if ( this.list.ContainsKey( name ) ) {
                return this.list[name];
            } else {
                throw new Exception( String.Format( "Type {0} not found in TypeMapping", name ) );
            }
        }


    }


    public class StanzaSerialization {
        public XmlDocument xdoc;

    }

    public class StanzaDeserializer : StanzaSerialization {
        protected TypeMapping typeMap;

        public StanzaDeserializer ( TypeMapping typeMap ) {
            this.typeMap = typeMap;
        }

        public repliback4.Net.Messages.Stanza deserialize ( XmlElement serEl ) {
            String key = String.Format("{0}-{1}", serEl.GetNamespaceOfPrefix( serEl.Prefix ), serEl.LocalName);
            Type type = this.typeMap.GetMappedType( key );

            ConstructorInfo cinfo = type.GetConstructor( new Type[0] );
            Stanza stanza = ( Stanza ) ( cinfo.Invoke( new object[0] ) );

            
            return stanza;

        }
    }
    public class StanzaSerializer : StanzaSerialization {

        protected XmlNamespaceManager nsManager;

        public StanzaSerializer ( ) {
            this.xdoc = new XmlDocument( );
        }

        public StanzaSerializer ( XmlDocument xdoc ) {
            this.xdoc = xdoc;
        }

        public StanzaSerializer ( XmlDocument xdoc, XmlNamespaceManager nameSpaceManager ) {
            this.xdoc = xdoc;
            this.nsManager = nameSpaceManager;
        }

        public XmlElement serialize ( object stanza ) {

            Type type = stanza.GetType( );

            XmlElement el = null;



            //object[] rattrs = type.GetCustomAttributes( true );
            //foreach ( Attributes.RequestAttr rattr in rattrs ) {
            //    if ( rattr.GetType( ) == typeof( Attributes.Request ) ) {
            //        name = rattr.Name;
            //    } else if ( rattr.GetType( ) == typeof( Attributes.RequestClass ) ) {
            //        prefix = rattr.Name;
            //    }
            //}

            Attributes.Request[] rq = ( Attributes.Request[] ) type.GetCustomAttributes( typeof( Attributes.Request ), true );
            Attributes.RequestClass[] rqcl = ( Attributes.RequestClass[] ) type.GetCustomAttributes( typeof( Attributes.RequestClass ), true );


            String name = rq.Length > 0 ? rq[rq.Length - 1].Name : "request";
            String prefix = rqcl.Length > 0 ? rqcl[rqcl.Length - 1].Name : "request";

            if ( this.nsManager == null ) {
                el = this.xdoc.CreateElement( name );
            } else {
                el = this.xdoc.CreateElement( prefix, name, this.nsManager.LookupNamespace( prefix ) );
            }


            //this.AddAttributes( el, stanza );
            //this.AddFields( el, type );


            FieldInfo[] fieldInfos = type.GetFields( );
            foreach ( FieldInfo fInfo in fieldInfos ) {

                object[] attrs = fInfo.GetCustomAttributes( true );
                foreach ( Attributes.RequestAttr attr in attrs ) {
                    //Console.WriteLine( "{0} {1} {2}", attr.GetType( ).Name, attr.Name, fInfo.GetValue( stanza ).ToString( ) );

                    if ( attr.GetType( ) == typeof( Attributes.Attr ) ) {
                        XmlAttribute xattr = this.xdoc.CreateAttribute( attr.Name );
                        xattr.Value = fInfo.GetValue( stanza ).ToString( );
                        el.Attributes.Append( xattr );
                    } else if ( attr.GetType( ) == typeof( Attributes.Field ) ) {

                        XmlElement xelem = this.xdoc.CreateElement( attr.Name );
                        XmlText xElemText = this.xdoc.CreateTextNode( fInfo.GetValue( stanza ).ToString( ) );
                        xelem.AppendChild( xElemText );
                        el.AppendChild( xelem );

                    } else {
                        //TODO: 
                    }

                }
            }

            return el;
        }
        //protected void AddAttributes ( XmlElement el,  Stanza stanza ) {
        //    FieldInfo[] fieldInfos = type.GetFields( );
        //    foreach ( FieldInfo fInfo in fieldInfos ) {
        //        object[] attrs = fInfo.GetCustomAttributes( typeof( Attributes.Attr ),true );
        //        if ( attrs.Length > 0 ) {
        //            Attributes.Attr attr = ( Attributes.Attr ) attrs[attrs.Length - 1];
        //            XmlAttribute xattr = this.xdoc.CreateAttribute( attr.Name );
        //            xattr.Value = fInfo.GetValue( stanza ).ToString( );
        //            el.Attributes.Append( xattr );                
        //        }
        //    }
        //}

        //protected void AddFields ( XmlElement el, Type type ) {

        //}

    }
}
*/